package com.thoughtservice.jspdoc.output;

import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hp.gagawa.java.elements.Caption;
import com.hp.gagawa.java.elements.Span;
import com.hp.gagawa.java.elements.Table;
import com.hp.gagawa.java.elements.Tbody;
import com.hp.gagawa.java.elements.Th;
import com.hp.gagawa.java.elements.Tr;
import com.thoughtservice.jspdoc.JSPFileList;
import com.thoughtservice.jspdoc.JSPPage;
import com.thoughtservice.jspdoc.RE;
import com.thoughtservice.jspdoc.RESyntaxException;
import com.thoughtservice.jspdoc.customize.Customizer;
import com.thoughtservice.jspdoc.utils.GenerateUtils;
import com.thoughtservice.jspdoc.utils.ProcessorUtils;

public class GenerateHtmlDoc {
	
	private final static Logger LOG = LoggerFactory.getLogger(GenerateHtmlDoc.class);
	
	private String rootSourceDir;
	private JSPFileList fileList;
	
	private Customizer customizer;
	
	public GenerateHtmlDoc(String rootSourceDir, JSPFileList fileList) {
		LOG.trace("Entering {}", "GenerateHtmlDoc");
		this.rootSourceDir = rootSourceDir;
		this.fileList = fileList;
		LOG.trace("Exiting {}", "GenerateHtmlDoc");
	}
	
	/**
	 * Print the HTML formatted text for the documentation about what import
	 * statements this JSPPage has.
	 * @param p JSPPage The page to display the imports for.
	 * @param i java.util.Iterator The list of imports.
	 * @param pw Writer The Writer to write the info to.
	 */
	public Table outputImports(JSPPage p, Iterator<String> i, Writer pw) throws IOException, RESyntaxException {
		LOG.trace("Entering {}", "outputImports");
		//Table definition
		Table importTable = createTable(JSPPageEnum.IMPORTS);

		int iIndex = 0;
		String color = "altColor";
		while (i.hasNext()) {
			String imp = (String) i.next();
			imp = imp.trim();
			String text;			
			if (imp.startsWith("com.alexmuc.") || imp.startsWith("ca.yourdecor.")) {
				String path = GenerateUtils.getRootRelPath(p.getName(), rootSourceDir);
				if (imp.endsWith("*")) {
					path += "../api/" + imp.substring(0, imp.length() - 1).replace('.', '/') + "package-summary.html";
				} else {
					path += "../api/" + imp.replace('.', '/') + ".html";
				}
//				String path = "path";
				text = "<a href=\"" + path + "\">" + imp + "</a>";
			} else {
				text = imp;
			}
			
			if(iIndex % 2 == 0){
				color = "rowColor";
			}else{
				color = "altColor";
			}
			Tr tableRow = new Tr();
			tableRow.setCSSClass(color);
			tableRow.appendText("<td class=\"colFirst\" scope=\"col\">" + text + "</td><td class=\"colLast\" scope=\"col\">&nbsp;</td>");
			
			importTable.appendChild(tableRow);
			iIndex++;
			//pw.write(" <tr><td align=\"left\">" + text + "</td></tr>\n");
		}
		//pw.write("</table>\n");
		LOG.trace("Exiting {}", "outputImports");			
		return importTable;
	}

	

	/**
	 * Write out the HTML documentation for the parameters found on
	 * the page
	 * 
	 * @param p ca.yourdecor.jspdoc.JSPPage The JSPPage to document.
	 * @param w java.io.Writer The destination of the documentation information.
	 */
	public Table outputParameters(JSPPage p, Writer pw) throws IOException {
		LOG.trace("Entering {}", "outputParameters");
		Iterator<String> i = p.getParamNames();
		Iterator<String> j = p.getParamTypes();
		Iterator<String> k = p.getParamDescs();
		Iterator<String> l = p.getParamSources();

		// Table definition
		/*pw.write("<table BORDER=\"1\" CELLPADDING=\"3\" CELLSPACING=\"0\" WIDTH=\"100%\">\n");
		
		// Table title
		pw.write(" <tr BGCOLOR=\"#CCCCFF\" CLASS=\"TableHeadingColor\"><td COLSPAN=\"4\"><font SIZE=\"+2\"><b>\n");
		pw.write("Parameters\n");
		pw.write("</b></font></td></tr>\n");

		pw.write(" <tr>\n");
		pw.write("  <td><b>Name</b></td>\n");
		pw.write("  <td><b>Type</b></td>\n");
		pw.write("  <td><b>Source</b></td>\n");
		pw.write("  <td><b>Description</b></td>\n");
		pw.write(" </tr>\n");*/
		
		Table importTable = createTable(JSPPageEnum.PARAMETERS);

		while (i.hasNext()) {
			
			String name = (String) i.next();
			String type = (String) j.next();
			String source = (String) l.next();
			String desc = (String) k.next();
			
			/*pw.write(" <tr>\n");
			pw.write("  <td>" + name   + "</td>\n");
			pw.write("  <td>" + type   + "</td>\n");
			pw.write("  <td>" + source + "</td>\n");
			pw.write("  <td>" + desc   + "</td>\n");
			pw.write(" </tr>\n");*/
			
			if (customizer != null && customizer.customizeParams()) {
				String customize = customizer.customizeParam(p, name, type, source, desc);
				if (customize != null && customize.length() > 0) {
					/*pw.write(" <tr>\n");
					pw.write("  <td></td>\n");
					pw.write("  <td colspan=\"3\">" + customizer.customizeParam(p, name, type, source, desc) + "</td>\n");
					pw.write(" </tr>\n");*/
					importTable.appendText(" <tr><td></td><td colspan=\"3\">" + customizer.customizeParam(p, name, type, source, desc) + "</td></tr>");
				}
			}
		}
		//pw.write("</table>\n");
		LOG.trace("Exiting {}", "outputParameters");
		return importTable;
	}


	/**
	 * Output a list of 'connections' about the JSPPage as documentation for the page.
	 * These are basically a set of a certain type of links from the given page
	 * to other pages in the system.
	 * 
	 * @param talbeTitle String The name to display as the heading for this list of Connections
	 * @param p JSPPage The page we're displaying the connections for
	 * @param i Iterator The list of connections to be displayed
	 * @param pw Writer Where the output goes
	 * @param type 
	 */
	public Table outputConnections(String tableTitle, JSPPage p, Iterator<File> i, Writer pw, int type) throws IOException, RESyntaxException {

		LOG.trace("Entering {}", "outputConnections");
		String rel = GenerateUtils.getRootRelPath(p.getName(), rootSourceDir);
		rel += "docs/";
		// Table definition
		/*pw.write("<table BORDER=\"1\" CELLPADDING=\"3\" CELLSPACING=\"0\" WIDTH=\"100%\">\n");
		
		// Table title
		pw.write(" <tr BGCOLOR=\"#CCCCFF\" CLASS=\"TableHeadingColor\"><td COLSPAN=\"2\"><font SIZE=\"+2\"><b>\n");
		pw.write(tableTitle + "\n");
		pw.write("</b></font></td></tr>\n");*/
		Table importTable = createTable(getEnum(type));

		int iIndex = 0;
		String color = "altColor";
		while (i.hasNext()) {
			File l = (File) i.next();
			String lName = l.toString();
			JSPPage dst = ProcessorUtils.getPage(lName, fileList);
			lName = lName.replace('\\', '/');

			if (lName.length() > rootSourceDir.length()) {
				String justName = lName.substring(rootSourceDir.length() + 1, lName.length());

				//String fullName = lName.substring(rootSourceDir.length(), lName.length());
//				System.out.println(fullName);
				RE re = new RE("\\.jsp$");
				String justHTMLName = re.subst(justName, ".html");
				/*pw.write("<tr>\n");
				pw.write(" <td valign=\"top\" align=\"left\"><b><a href=\""
						+ rel
						+ justHTMLName
						+ "\">"
						+ justName
						+ "</a></b></td>\n");
				pw.write(" <td valign=\"top\" align=\"left\">");*/
				if(iIndex % 2 == 0){
					color = "rowColor";
				}else{
					color = "altColor";
				}
				importTable.appendText("<tr class=\""+color+"\">\n");
				importTable.appendText(" <td class=\"colFirst\"><b><a href=\""
						+ rel
						+ justHTMLName
						+ "\">"
						+ justName
						+ "</a></b></td>\n");
				importTable.appendText(" <td class=\"colLast\">");
//				System.out.println("\t!" + dst);
				if (dst != null)
					importTable.appendText(dst.getPageDescShort());
				importTable.appendText(" </td>\n");
				importTable.appendText("</tr>\n");
				iIndex++;
			} else {
				System.out.println("**********SKIPPING LINK");
			}
		}
		/*pw.write("</table>\n");
		pw.write("</td></tr></table>\n\n");*/
		LOG.trace("Exiting {}", "outputConnections");
		return importTable;

	}
	
	/**
	 * Print the HTML formatted text for the documentation on jsp page used as tile in other pages
	 * @param p JSPPage The page to display the imports for.
	 * @param i java.util.Iterator The list of imports.
	 * @param pw Writer The Writer to write the info to.
	 */
	public Table outputTilesInserts(JSPPage p, Iterator<String> i, Writer pw, int type) throws IOException, RESyntaxException {

		LOG.trace("Entering {}", "outputTilesInserts");
		String rel = GenerateUtils.getRootRelPath(p.getName(), rootSourceDir);
		rel += "docs/";
		
		// Table definition
		Table importTable = createTable(getEnum(type));
		/*pw.write("<table BORDER=\"1\" CELLPADDING=\"3\" CELLSPACING=\"0\" WIDTH=\"100%\">\n");
		
		// Table title
		pw.write(" <tr BGCOLOR=\"#CCCCFF\" CLASS=\"TableHeadingColor\"><td COLSPAN=\"3\"><font SIZE=\"+2\"><b>\n");
		pw.write("Used as tile In \n");
		pw.write("</b></font></td></tr>\n");
		
		//Table heading
		pw.write(" <tr BGCOLOR=\"#CCFFFF\" CLASS=\"TableHeadingColor\"><th COLSPAN=\"1\"><font SIZE=\"+2\"><b>\n");
		pw.write("Tile Name\n");
		pw.write("</b></font></th>");
		pw.write("<th COLSPAN=\"3\"><font SIZE=\"+2\"><b>Used In \n</th>");
		pw.write("</tr>\n");*/

		int iIndex = 0;
		String color = "altColor";
		while (i.hasNext()) {
			String tileName = (String) i.next();
			File l = (File) p.getTilePath(tileName);
			String lName = l.toString();
			JSPPage dst = ProcessorUtils.getPage(lName, fileList);
			lName = lName.replace('\\', '/');

			if (lName.length() > rootSourceDir.length()) {
				String justName = lName.substring(rootSourceDir.length() + 1, lName.length());

				//String fullName = lName.substring(rootSourceDir.length(), lName.length());
//				System.out.println(fullName);
				RE re = new RE("\\.jsp$");
				String justHTMLName = re.subst(justName, ".html");
				/*pw.write("<tr>\n");
				pw.write("<td align=\"left\">" + tileName + "</td>");
				pw.write(" <td valign=\"top\" align=\"left\"><b><a href=\""
						+ rel
						+ justHTMLName
						+ "\">"
						+ justName
						+ "</a></b></td>\n");*/
				//pw.write(" <td valign=\"top\" align=\"left\">");
				if(iIndex % 2 == 0){
					color = "rowColor";
				}else{
					color = "altColor";
				}
				importTable.appendText("<tr class=\""+color+"\">\n<td class=\"colFirst\">" + tileName + "</td>");
				importTable.appendText(" <td class=\"colLast\"><a href=\""
						+ rel
						+ justHTMLName
						+ "\">"
						+ justName
						+ "</a></td>\n");
				if (dst != null)
					//pw.write(dst.getPageDescShort());
					importTable.appendText(dst.getPageDescShort());
				//pw.write(" </td>\n");
				//pw.write("</tr>\n");
				importTable.appendText("</td>\n</tr>");
				iIndex++;
			} else {
				System.out.println("**********SKIPPING LINK");
			}		
		}
		//pw.write("</table>\n");
		LOG.trace("Exiting {}", "outputTilesInserts");
		return importTable;
	}
	
	/**
	 * Print the HTML formatted text for the documentation on Tile imports used in the current JSP page
	 * @param p JSPPage The page to display the imports for.
	 * @param i java.util.Iterator The list of imports.
	 * @param pw Writer The Writer to write the info to.
	 * @param type 
	 */
	public Table outputTilesInsertsIn(JSPPage p, Iterator<String> i, Writer pw, int type) throws IOException, RESyntaxException {

		LOG.trace("Entering {}", "outputTilesInsertsIn");
		String rel = GenerateUtils.getRootRelPath(p.getName(), rootSourceDir);
		rel += "docs/";
		
		// Table definition
		Table importTable = createTable(getEnum(type));
		/*pw.write("<table BORDER=\"1\" CELLPADDING=\"3\" CELLSPACING=\"0\" WIDTH=\"100%\">\n");
		
		// Table title
		pw.write(" <tr BGCOLOR=\"#CCCCFF\" CLASS=\"TableHeadingColor\"><td COLSPAN=\"3\"><font SIZE=\"+2\"><b>\n");
		pw.write("Tile Inserts In Page \n");
		pw.write("</b></font></td></tr>\n");
		
		//Table heading
		pw.write(" <tr BGCOLOR=\"#CCFFFF\" CLASS=\"TableHeadingColor\"><th COLSPAN=\"1\"><font SIZE=\"+2\"><b>\n");
		pw.write("Tile Name\n");
		pw.write("</b></font></th>");
		pw.write("<th COLSPAN=\"3\"><font SIZE=\"+2\"><b>Used In \n</th>");
		pw.write("</tr>\n");*/
		
		int iIndex = 0;
		String color = "altColor";
		while (i.hasNext()) {
			String tileName = (String) i.next();			
			File l = (File) p.getTileInPath(tileName);
			String lName = l.toString();
			//System.out.println("tileName -->"+tileName+" path  --> "+lName);
			JSPPage dst = ProcessorUtils.getPage(lName, fileList);
			lName = lName.replace('\\', '/');

			if (lName.length() > rootSourceDir.length()) {
				String justName = lName.substring(rootSourceDir.length() + 1, lName.length());

				//String fullName = lName.substring(rootSourceDir.length(), lName.length());
//				System.out.println(fullName);
				RE re = new RE("\\.jsp$");
				String justHTMLName = re.subst(justName, ".html");
				/*pw.write("<tr>\n");
				pw.write("<td align=\"left\">" + tileName + "</td>");
				pw.write(" <td valign=\"top\" align=\"left\"><b><a href=\""
						+ rel
						+ justHTMLName
						+ "\">"
						+ justName
						+ "</a></b></td>\n");*/
				//pw.write(" <td valign=\"top\" align=\"left\">");
//				System.out.println("\t!" + dst);
				if(iIndex % 2 == 0){
					color = "rowColor";
				}else{
					color = "altColor";
				}
				importTable.appendText("<tr class=\""+color+"\">\n<td class=\"colFirst\">" + tileName + "</td>");
				importTable.appendText("<td class=\"colLast\"><a href=\""
						+ rel
						+ justHTMLName
						+ "\">"
						+ justName
						+ "</a></td>\n");
				if (dst != null)
					//pw.write(dst.getPageDescShort());
					importTable.appendText(dst.getPageDescShort());
				//pw.write(" </td>\n");
				//pw.write("</tr>\n");
				importTable.appendText("</td>\n</tr>\n");
				iIndex++;
			} else {
				LOG.debug("**********SKIPPING LINK");
			}		
		}
		//pw.write("</table>\n");
		LOG.trace("Exiting {}", "outputTilesInsertsIn");
		return importTable;

	}



	public void setCustomizer(Customizer customizer) {
		this.customizer = customizer;
	}
	
	/**
	 * Generates Next gen genric table which will be used by all methods
	 * @param imports 
	 * @return
	 */
	private Table createTable(JSPPageEnum page) {
		LOG.trace("Entering {}", "createTable");
		Table contentContainerTable = new Table();
		contentContainerTable.setCSSClass("overviewSummary");
		contentContainerTable.setBorder("0");
		contentContainerTable.setCellpadding("0");
		contentContainerTable.setCellspacing("0");
		contentContainerTable.setSummary("Java imports used in page");
		
		//Set the caption
		Caption caption = new Caption();
		Span captionSpan = new Span();
		captionSpan.appendText(page.getName());
		Span captionSpanEnd = new Span();
		captionSpanEnd.setCSSClass("tabEnd");
		captionSpanEnd.appendText("&nbsp;");
		caption.appendChild(captionSpan);
		caption.appendChild(captionSpanEnd);
		
		contentContainerTable.appendChild(caption);
		
		//Create heading <th>
		Tbody headingTbody = new Tbody();
		Tr headingTr = new Tr();
		int i = 0;
		for(String s : page.columnDescriptions()){
			Th heading1 = new Th();
			if(i ==0){
				heading1.setCSSClass("colFirst");
			}else{
				heading1.setCSSClass("colLast");
			}			
			heading1.appendText(s);			
			headingTr.appendChild(heading1);
			i++;
		}
		
		
		/*Th heading2 = new Th();
		heading2.setCSSClass("colLast");
		heading2.appendText("Description");
		
		
		headingTr.appendChild(heading2);*/
		
		headingTbody.appendChild(headingTr);
		
		contentContainerTable.appendChild(headingTbody);
		LOG.trace("Exiting {}", "createTable");
		return contentContainerTable;
				
	}
	
	public JSPPageEnum getEnum(int key) {
		switch(key){
			case 0:
				return JSPPageEnum.LINKS_TO;				
			case 1:
				return JSPPageEnum.LINKSFROM;
			case 2:
				return JSPPageEnum.S_INCLUDES;
			case 3:
				return JSPPageEnum.S_INCLUDEDIN;
			case 4:
				return JSPPageEnum.REDIRECTS;
			case 5:
				return JSPPageEnum.D_INCLUDES;
			case 6:
				return JSPPageEnum.D_INCLUDEDIN;
			case 7:
				return JSPPageEnum.LINKSTOFORM;
			case 8:
				return JSPPageEnum.ERRORPAGE;
			case 9:
				return JSPPageEnum.TILE_INSERTS;
			case 10:
				return JSPPageEnum.TILE_INSERTS_INPAGE;
			case 11:
				return JSPPageEnum.IMPORTS;
			case 12:
				return JSPPageEnum.PARAMETERS;
		}
		return null;		
	}

}
